#ifndef TCPSERVER_HPP
#define TCPSERVER_HPP
#include <arpa/inet.h>
#include <netinet/in.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/types.h>

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>

#include "log.hpp"

Log lg;

enum { SOCKET_ERR = 2, BIND_ERR, LISTEN_ERR };
const int backlog = 5;

class TcpServer {
 public:
  // 构造函数初始化 TcpServer 类
  TcpServer(uint16_t port = defaultport) : listen_sockfd_(-1), port_(port) {}

  void Init() {
    // 创建套接字 绑定 监听

    // 套接字创建
    listen_sockfd_ = socket(AF_INET, SOCK_STREAM, 0);
    if (listen_sockfd_ < 0) {
      lg(FATAL, "create socket error , error message: %s", strerror(errno));
      exit(SOCKET_ERR);
    }
    lg(INFO, "create socket sucess, sockfd:%d", listen_sockfd_);

    // 绑定
    struct sockaddr_in local;
    memset(&local, 0, sizeof(local));
    local.sin_family = AF_INET;
    local.sin_port = htons(port_);
    local.sin_addr.s_addr = INADDR_ANY;

    socklen_t len = sizeof(local);
    if (bind(listen_sockfd_, (sockaddr*)&local, len) < 0) {
      lg(FATAL, "bind error , error message: %s", strerror(errno));
      exit(BIND_ERR);
    }

    // 设置监听
    if (listen(listen_sockfd_, backlog) < 0) {
      lg(FATAL, "listen error , error message: %s", strerror(errno));
      exit(LISTEN_ERR);
    }
  }

  void Server(int sockfd, const std::string& ip, const uint16_t port) {
    char buff[4096];
    while (true) {
      int n = read(sockfd, buff, sizeof(buff));
      if (n > 0) {
        buff[n] = 0;
        std::cout << "Client send a message@ " << buff << std::endl;
        std::string ret("Server get a message# ");
        ret += buff;
        write(sockfd, ret.c_str(), ret.size());  // 发回客户端
      } else if (n == 0) {
        lg(INFO, "Client %s:%d quit... ", ip.c_str(), port);
        break;
      } else {
        lg(WARNING, "read error , error message: %s", strerror(errno));
      }
    }
  }

  void Start() {
    // 获取连接 处理客户端请求

    // signal(SIGCHLD, SIG_IGN);  // 忽略 SIGCHLD 信号

    lg(INFO, "TcpServer start sucess...");
    while (true) {
      // 获取连接
      struct sockaddr_in local;
      memset(&local, 0, sizeof(local));
      socklen_t len = sizeof(local);
      int sockfd = accept(listen_sockfd_, (struct sockaddr*)&local, &len);
      if (sockfd < 0) {
        lg(WARNING, "accept error , error message: %s", strerror(errno));
        continue;
      }

      uint16_t client_port = ntohs(local.sin_port);
      char ipstr[32];
      inet_ntop(AF_INET, &(local.sin_addr), ipstr, sizeof(ipstr));

      lg(INFO, "accept sucess , sockfd :%d ,client ip :%s ,client port :%d",
         sockfd, ipstr, client_port);
      // 1. 处理请求
      // Server(sockfd, ipstr, client_port);
      // close(sockfd);

      // 2.
      // pid_t id = fork();
      // if(id == 0){
      //   // child
      //   close(listen_sockfd_);
      //   Server(sockfd,ipstr,client_port);
      //   close(sockfd);
      //   exit(0);
      // }
      // else if(id<0){
      //  // error
      //  lg(WARNING,"fork error, error messgae: %s",strerror(errno));
      //  continue;
      // }
      // else{
      //   // parent
      //   close(sockfd);
      // }

      // 3.
      pid_t id = fork();
      if(id == 0){
        // 中间进程
        if(fork() == 0){
          // 孙子进程
          close(listen_sockfd_);
          Server(sockfd, ipstr, client_port);
          close(sockfd);
          exit(0);
        }
        exit(0);
      }
      else if(id<0){
       // error
       lg(WARNING,"fork error, error messgae: %s",strerror(errno));
       continue;
      }
      else{
        // parent
        close(sockfd);
      }
    }

  }

  ~TcpServer() {
    // 清理操作
    if (listen_sockfd_ != -1) {
      close(listen_sockfd_);
      listen_sockfd_ = -1;
    }
  }

 private:
  int listen_sockfd_;  // 服务端的监听套接字描述符
  uint16_t port_;      // 服务端的监听端口

 protected:
  static const uint16_t defaultport;  // 默认端口号
};
const uint16_t TcpServer::defaultport = 8080;  // 默认端口号初始化

#endif